﻿using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using TIBCO.Rendezvous;

namespace Tibco.ServiceModel
{
    internal sealed class TibcoReplyChannelListener<TChannel> : TibcoChannelListenerBase<IReplyChannel>
    where TChannel : class, IChannel
    {
        private IReplyChannel m_channel;
        private NetTransport m_transport;
        private CMQueueTransport m_cmTransport;
        private TibcoTransportBindingElement bindingElement;

        internal TibcoReplyChannelListener(TibcoTransportBindingElement bindingElement, BindingContext context) : base(context)
        {
            this.m_channel = null;
            this.m_transport = null;
            this.m_cmTransport = null;

            this.bindingElement = bindingElement;
        }

        protected override IReplyChannel OnAcceptChannel(TimeSpan timeout)
        {
            if (this.m_channel != null)
            {
                return null;
            }
            this.m_channel = new TibcoReplyChannel(base.Context, this.m_cmTransport, new EndpointAddress(this.Uri.ToString()));
            this.m_channel.Closed += (s, e) => { base.Close(); };
            return this.m_channel;
        }

        protected override void OnClose(TimeSpan timeout)
        {
            Debug.Out("TibcoReplyChannelListener.OnClose()", "Closing...");

            this.m_channel?.Close();
            this.m_transport?.Destroy();
            this.m_cmTransport?.Destroy();

            this.m_channel = null;
            this.m_transport = null;
            this.m_cmTransport = null;            
        }

        protected override void OnOpen(TimeSpan timeout)
        {
            TIBCO.Rendezvous.Environment.Open();

            Debug.Out("TibcoReplyChannelListener.OnOpen()", "Tibco environment opened");

            this.m_transport = new NetTransport(bindingElement.Service, bindingElement.Network, bindingElement.Deamon);
            this.m_cmTransport = new CMQueueTransport(this.m_transport, bindingElement.DQName);
        }

        protected override bool OnWaitForChannel(TimeSpan timeout)
        {
            return false;
        }
    }
}